"use strict";
/*
  装饰器 - -  在其他语言中 这个都不算是新东西
    装饰器：一种特殊的类型声明，可以附加在类的声明、方法、属性上，可以修改类的行为

    通俗的将装饰器本质上就是一个方法，可以注入到类、方法、属性参数来扩展类、方法、属性的功能

    常见的装饰器有：类装饰器、属性装饰器、方法装饰器、参数装饰器

    装饰器的写法：普通装饰器（无法传参）  、  装饰器工厂（可传参）

    装饰器是过去几年中JS最大的成就之一，已经是ES7的标准特性之一
*/
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
// 1.类装饰器
// 1.1 普通装饰器  （不能传参）
function modification1(target) {
    console.log(target); // 打印出 [Function: bookStore]  bookstore 类 当前类
    /*
      因为target表示的是当前类  直接通过类名点成员们访问的应该是静态方法  而这个类没有设置静态
        方法  所以放回的自然是 undefined   实例属性和方法只有通过new出来的实例才可以调用
    */
    console.log(target.author); // undefined
    console.log(target.books); // undefined
    // 在当前类的原型上可以扩展属性和方法
    target.prototype.age = 22;
}
var bookStore = /** @class */ (function () {
    function bookStore(book) {
        this.author = 'Jimmy';
        this.books = ['htmml'];
        // 构造函数不需要指定返回值类型
        this.books.push(book);
    }
    bookStore.prototype.getBook = function () {
        console.log(this.books);
    };
    bookStore = __decorate([
        modification1 //  调用装饰器的时候这里一定不能加分号
    ], bookStore);
    return bookStore;
}());
var JimmyBook = new bookStore('js'); // 给类指定一个any类型就不会报错
console.log(JimmyBook.age);
// 1.2 装饰器工厂 （可以传递参数）
// 装饰器工程无非就是在 基础装饰器的 里面 再嵌套一个方法 - - 嵌套的方法可以获取参数
// 但是要知道 被嵌套的 方法是拿来传参的  父装饰器才是获取对象的
function modification2(value) {
    // 嵌套方法获取参数
    return function paramsFun(target) {
        console.log(target); // movie类
        console.log(value); // node.js大法
        target.prototype['msg'] = value;
    };
}
var movie = /** @class */ (function () {
    function movie(movie) {
        this.auther = 'xuexue';
        this.movieList = [];
        this.movieList.push(movie);
    }
    movie = __decorate([
        modification2('node.js大法')
    ], movie);
    return movie;
}());
var JimmyMove = new movie('TypeScript全套教程');
console.log(JimmyMove.msg); //  node.js大法
/*
  总结：
    装饰器真的超级好用 可以让我们在不修改一个类内部结构的情况下， 对类的 属性 方法进行扩展
*/
// 2.属性修饰器
//  属性装饰器表达式会在运行时当做函数被调用，传入下列两个参数
// 1： 对于静态成员来说是类的构造函数  对于实例成员来说是类的原型对象
// 2： 成员的名字
function attribute1(params) {
    console.log(params); // www.baidu.com
    return function (value1, value2) {
        console.log('属性装饰器', value1); // course 原型方法
        console.log('属性装饰器', value2); // 使用修饰器的那个属性
    };
}
var course = /** @class */ (function () {
    function course() {
        this.sid = 173117002;
    }
    course.prototype.getData = function () {
        console.log(this.name);
    };
    __decorate([
        attribute1('http://www.baidu.com')
    ], course.prototype, "name", void 0);
    return course;
}());
var java = new course();
